package com.wanmait.employment.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

//@Component
//@Aspect//切面类
public class DemoAspect {

    //定义切入点表达式,第一个* 表示任意的返回类型，第二个*表示任意的类或者接口，第三个*表示任意的方法
    //(*)任意的一个参数的方法,(*,*)任意类型的两个参数的方法，(..)表示任意的参数个数和参数类型
    @Pointcut("execution(* com.wanmait.employment.service.*.*(..))")
    public void pointcuntExpression(){}

    //前置通知  哪个方法的执行被切入了，哪个方法就是连接点，比如QuestionService.list()方法被切入了，连接点JoinPoint就是list()方法
    @Before("pointcuntExpression()")
    public void before(JoinPoint joinPoint){
        System.out.println("before..............");
        System.out.println("目标类："+joinPoint.getTarget().getClass().getName());
        System.out.println("方法名："+joinPoint.getSignature().getName());
        System.out.println("参数："+ Arrays.asList(joinPoint.getArgs()));
    }
    //后置通知，不管目标方法执行成功或者失败都会执行
    @After("pointcuntExpression()")
    public void after(JoinPoint joinPoint){
        System.out.println("after.................");
    }
    //后置通知，异常通知,目标方法抛出异常执行的通知
    @AfterThrowing(value = "pointcuntExpression()",throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint,Exception ex){
        System.out.println("afterThrowing.................");
        System.out.println(ex.getMessage());
    }
    //后置通知，返回通知，目标方法执行成功后执行的通知
    @AfterReturning(value = "pointcuntExpression()",returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint,Object returnValue){
        System.out.println("afterReturning...............");
        System.out.println(returnValue);
    }

    //环绕通知
    @Around("pointcuntExpression()")
    public Object around(ProceedingJoinPoint joinPoint) {
        System.out.println("around before........................");
        long begin = System.currentTimeMillis();
        //手工调用
        Object returnValue = null;
        try {
            returnValue = joinPoint.proceed();

        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("执行时间："+(end-begin)+"毫秒");
        System.out.println("around after........................");

        return returnValue;
    }
}













